#include <func.h>
#include "BlockQ.h"

typedef struct {
	pthread_t* threads;
	int nums;
	BlockQ* q;
} ThreadPool;

void* start_routine(void* arg) {
	BlockQ* q = (BlockQ*) arg;
	pthread_t tid = pthread_self();

	for (;;) {
		E task_id = blockq_pop(q); // 如果没有任务，则阻塞
		if (task_id == -1) {
			pthread_exit(NULL);
		}

		printf("Thread 0x%lx: executing task #%d\n", tid, task_id);
		/* sleep(1); */
		/* printf("Thread 0x%lx: task #%d done\n", tid, task_id); */
	}
}

ThreadPool* threadpool_create(int n) {
	ThreadPool* pool = (ThreadPool*)malloc(sizeof(ThreadPool));
	pool->threads = (pthread_t*)malloc(n * sizeof(pthread_t));
	pool->nums = n;
	pool->q = blockq_create();

	// 创建n个工作线程
	for(int i = 0; i < n; i++) {
		pthread_create(pool->threads + i, NULL, start_routine, pool->q);
	}

	return pool;
}

int main(int argc, char* argv[])
{
	// 1. 创建线程池
	ThreadPool* pool = threadpool_create(8);

	// 2. 往阻塞队列中放任务
	for (int i = 1; i <= 100; i++) {
		blockq_push(pool->q, i);
	}
	
	// 3. 退出线程池
	sleep(3);
	// a. 暴力退出
	/* for (int i = 0; i < pool->nums; i++) { */
	/* 	pthread_cancel(pool->threads[i]); */
	/* } */

	// b. 优雅退出
	for(int i = 0; i < pool->nums; i++) {
		blockq_push(pool->q, -1);
	}
    printf("push -1.\n");

	for(int i = 0; i < pool->nums; i++) {
		pthread_join(pool->threads[i], NULL);
	}
    return 0;
}

